const express = require('express')
const multer = require('multer')
const csv = require('csv-parser')
const fs = require('fs')
const path = require('path')
const cors = require('cors')
const iconv = require('iconv-lite')

// 数据存储路径
const DATA_DIR = path.join(__dirname, 'data')
const DATA_FILE = path.join(DATA_DIR, 'data.json')
const FILTER_OPTIONS_FILE = path.join(DATA_DIR, 'filterOptions.json')

// 确保数据目录存在
if (!fs.existsSync(DATA_DIR)) {
  fs.mkdirSync(DATA_DIR, { recursive: true })
}

// 确保上传目录存在
const uploadDir = path.join(__dirname, 'uploads')
if (!fs.existsSync(uploadDir)) {
  fs.mkdirSync(uploadDir, { recursive: true })
}

// 从文件加载数据
let csvData = []
let filterOptions = {
  years: new Set(),
  competitions: new Set(),
  tracks: new Set(),
  provinces: new Set(),
  schools: new Set()
}

// 加载持久化的数据
function loadPersistedData() {
  try {
    if (fs.existsSync(DATA_FILE)) {
      csvData = JSON.parse(fs.readFileSync(DATA_FILE, 'utf8'))
    }
    if (fs.existsSync(FILTER_OPTIONS_FILE)) {
      const loadedOptions = JSON.parse(fs.readFileSync(FILTER_OPTIONS_FILE, 'utf8'))
      Object.keys(loadedOptions).forEach(key => {
        filterOptions[key] = new Set(loadedOptions[key])
      })
    }
  } catch (error) {
    console.error('Error loading persisted data:', error)
  }
}

// 保存数据到文件
function persistData() {
  try {
    fs.writeFileSync(DATA_FILE, JSON.stringify(csvData, null, 2))
    const serializedOptions = {}
    Object.keys(filterOptions).forEach(key => {
      serializedOptions[key] = Array.from(filterOptions[key])
    })
    fs.writeFileSync(FILTER_OPTIONS_FILE, JSON.stringify(serializedOptions, null, 2))
  } catch (error) {
    console.error('Error persisting data:', error)
  }
}

// 初始加载数据
loadPersistedData()

const storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, uploadDir)
  },
  filename: function (req, file, cb) {
    cb(null, Date.now() + '-' + file.originalname)
  }
})

const upload = multer({ 
  storage: storage,
  fileFilter: function (req, file, cb) {
    if (!file.originalname.toLowerCase().endsWith('.csv')) {
      return cb(new Error('只支持CSV文件'))
    }
    cb(null, true)
  }
})

const app = express()

// 预期的CSV列名
const EXPECTED_HEADERS = [
  '序号', '学校', '赛项', '赛道', '奖项', '组别', 
  '省份', '市区', '年份', '届数', '学院', 
  '指导教师', '联系电话', '组织名称', '备注'
]

// CSV列名到数据字段的映射
const COLUMN_MAPPING = {
  '学校': 'school',
  '赛项': 'competition',
  '赛道': 'track',
  '省份': 'province',
  '市区': 'city',
  '年份': 'year',
  '届数': 'session',
  '奖项': 'award',
  '组别': 'group',
  '学院': 'department',
  '指导教师': 'teacher',
  '联系电话': 'phone',
  '组织名称': 'organization',
  '备注': 'remarks'
}

app.use(cors())
app.use(express.json())

// 添加一个用于生成记录唯一键的函数
function generateRecordKey(record) {
  // 使用多个字段组合生成唯一键
  return `${record.school}_${record.competition}_${record.track}_${record.year}_${record.session}_${record.teacher}`
}

// 添加记录去重函数
function deduplicateRecords(existingData, newData) {
  const recordMap = new Map()
  
  // 先处理现有数据
  existingData.forEach(record => {
    const key = generateRecordKey(record)
    recordMap.set(key, record)
  })
  
  // 合并新数据，相同键的记录会被覆盖
  newData.forEach(record => {
    const key = generateRecordKey(record)
    recordMap.set(key, record)
  })
  
  return Array.from(recordMap.values())
}

app.post('/api/upload', upload.single('file'), async (req, res) => {
  if (!req.file) {
    return res.status(400).json({ message: '未找到上传的文件' })
  }

  try {
    const results = []
    let headers = null

    await new Promise((resolve, reject) => {
      // 创建GBK编码的读取流
      const fileStream = fs.createReadStream(req.file.path)
      const gbkStream = fileStream.pipe(iconv.decodeStream('gbk'))

      gbkStream
        .pipe(csv())
        .on('headers', (csvHeaders) => {
          headers = csvHeaders
          // 验证CSV文件格式
          const missingHeaders = EXPECTED_HEADERS.filter(
            header => !csvHeaders.includes(header)
          )
          if (missingHeaders.length > 0) {
            reject(new Error(`CSV文件缺少必需的列：${missingHeaders.join(', ')}`))
          }
        })
        .on('data', (row) => {
          // 将中文列名映射到英文字段名
          const mappedData = {}
          Object.entries(COLUMN_MAPPING).forEach(([zhKey, enKey]) => {
            mappedData[enKey] = row[zhKey]
          })
          results.push(mappedData)
        })
        .on('end', () => {
          // 合并并去重数据
          csvData = deduplicateRecords(csvData, results)
          
          // 重新收集筛选选项
          Object.keys(filterOptions).forEach(key => {
            filterOptions[key].clear()
          })
          
          csvData.forEach(record => {
            filterOptions.years.add(record.year)
            filterOptions.competitions.add(record.competition)
            filterOptions.tracks.add(record.track)
            filterOptions.provinces.add(record.province)
            filterOptions.schools.add(record.school)
          })
          
          resolve()
        })
        .on('error', (error) => {
          reject(new Error('CSV文件解析失败：可能是文件格式错误或编码问题'))
        })
    })

    // 保存合并后的数据
    persistData()

    // 删除文件前检查文件是否存在
    if (fs.existsSync(req.file.path)) {
      fs.unlinkSync(req.file.path)
    }

    res.json({ 
      message: '文件上传成功', 
      totalRecords: csvData.length 
    })
  } catch (error) {
    // 删除可能存在的临时文件
    if (req.file && fs.existsSync(req.file.path)) {
      fs.unlinkSync(req.file.path)
    }
    console.error('File processing error:', error)
    res.status(500).json({ message: error.message || '文件处理失败' })
  }
})

app.get('/api/filter-options-from-data', (req, res) => {
  const currentFilters = req.query;
  let filteredData = [...csvData];

  // 应用现有筛选条件
  if (currentFilters.years?.length) {
    const yearsArray = currentFilters.years.split(',');
    filteredData = filteredData.filter(item => yearsArray.includes(item.year));
  }
  if (currentFilters.competitions?.length) {
    const competitionsArray = currentFilters.competitions.split(',');
    filteredData = filteredData.filter(item => competitionsArray.includes(item.competition));
  }
  if (currentFilters.tracks?.length) {
    const tracksArray = currentFilters.tracks.split(',');
    filteredData = filteredData.filter(item => tracksArray.includes(item.track));
  }
  if (currentFilters.provinces?.length) {
    const provincesArray = currentFilters.provinces.split(',');
    filteredData = filteredData.filter(item => provincesArray.includes(item.province));
  }
  if (currentFilters.schools?.length) {
    const schoolsArray = currentFilters.schools.split(',');
    filteredData = filteredData.filter(item => schoolsArray.includes(item.school));
  }

  // 从筛选后的数据中收集可用的选项
  const availableOptions = {
    years: new Set(),
    competitions: new Set(),
    tracks: new Set(),
    provinces: new Set(),
    schools: new Set()
  };

  filteredData.forEach(record => {
    availableOptions.years.add(record.year);
    availableOptions.competitions.add(record.competition);
    availableOptions.tracks.add(record.track);
    availableOptions.provinces.add(record.province);
    availableOptions.schools.add(record.school);
  });

  const options = {
    years: Array.from(availableOptions.years).sort().reverse(),
    competitions: Array.from(availableOptions.competitions).map(c => ({ value: c, label: c })),
    tracks: Array.from(availableOptions.tracks).map(t => ({ value: t, label: t })),
    provinces: Array.from(availableOptions.provinces).map(p => ({ value: p, label: p })),
    schools: Array.from(availableOptions.schools).map(s => ({ value: s, label: s }))
  };

  res.json(options);
});

app.post('/api/data', (req, res) => {
  const filters = req.body
  let filteredData = [...csvData]

  // 应用筛选条件
  if (filters.years?.length) {
    filteredData = filteredData.filter(item => filters.years.includes(item.year))
  }
  if (filters.competitions?.length) {
    filteredData = filteredData.filter(item => filters.competitions.includes(item.competition))
  }
  if (filters.tracks?.length) {
    filteredData = filteredData.filter(item => filters.tracks.includes(item.track))
  }
  if (filters.provinces?.length) {
    filteredData = filteredData.filter(item => filters.provinces.includes(item.province))
  }
  if (filters.schools?.length) {
    filteredData = filteredData.filter(item => filters.schools.includes(item.school))
  }

  res.json(filteredData)
})

// 添加数据清理接口
app.delete('/api/data', (req, res) => {
  csvData = []
  Object.keys(filterOptions).forEach(key => {
    filterOptions[key].clear()
  })
  persistData()
  res.json({ message: '数据已清除' })
})

// 添加数据统计接口
app.get('/api/stats', (req, res) => {
  const stats = {
    totalRecords: csvData.length,
    filterCounts: {
      years: filterOptions.years.size,
      competitions: filterOptions.competitions.size,
      tracks: filterOptions.tracks.size,
      provinces: filterOptions.provinces.size,
      schools: filterOptions.schools.size
    }
  }
  res.json(stats)
})

const PORT = 3000
app.listen(PORT, () => {
  console.log(`Server is running on port ${PORT}`)
})
